﻿using System;
using System.Collections.Generic;

namespace Games.Horse64
{
    class Game
    {
        public const int LENGTH = 8;
        private bool[,] status = new bool[1, 1];
        private int[,] moves = new int[8, 2] { { 1, 2 }, { 1, -2 }, { -1, -2 }, { -1, 2 }, { 2, 1 }, { 2, -1 }, { -2, -1 }, { -2, 1 } };
        private Stack<(int, int)> steps = new Stack<(int, int)>();

        public void Init()
        {
            this.status = new bool[LENGTH, LENGTH];
            var rd = new Random();
            this.StartX = this.CurrentX = rd.Next(LENGTH);
            this.StartY = this.CurrentY = rd.Next(LENGTH);
            this.status[StartX, StartY] = true;
            this.steps.Clear();
        }

        public void Reload()
        {
            this.status = new bool[LENGTH, LENGTH];
            this.CurrentX = this.StartX;
            this.CurrentY = this.StartY;
            this.status[StartX, StartY] = true;
            this.steps.Clear();
        }

        public bool Visit(int x, int y)
        {
            if(status[x, y])
            {
                return false;
            }
            var dx = Math.Abs(CurrentX - x);
            var dy = Math.Abs(CurrentY - y);
            if(dx + dy != 3)
            {
                return false;
            }
            if(Math.Abs(dx - dy) != 1)
            {
                return false;
            }
            this.steps.Push((CurrentX, CurrentY));
            CurrentX = x;
            CurrentY = y;
            status[x, y] = true;
            return true;
        }

        public bool Back(out int x, out int y)
        {
            (x, y) = (0, 0);
            if(this.steps.Count == 0)
            {
                return false;
            }
            (x, y) = this.steps.Pop();
            if(!status[x, y])
            {
                return false;
            }
            status[CurrentX, CurrentY] = false;
            CurrentX = x;
            CurrentY = y;
            return true;
        }

        public bool CanMove()
        {
            for(int i = 0; i < 8; i++)
            {
                if(IsEmpty(moves[i, 0], moves[i, 1]))
                {
                    return true;
                }
            }
            return false;
        }

        //public int Count { get; private set; }
        public int CurrentX { get; private set; }
        public int CurrentY { get; private set; }
        public int StartX { get; private set; }
        public int StartY { get; private set; }

        private bool IsEmpty(int x, int y)
        {
            var tx = CurrentX + x;
            if(tx < 0 || tx >= LENGTH)
            {
                return false;
            }
            var ty = CurrentY + y;
            if(ty < 0 || ty >= LENGTH)
            {
                return false;
            }
            return !status[tx, ty];
        }
    }
}